001 /* 002 * Copyright 2006 Stephen J. McConnell. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.util; 020 021 import java.io.IOException; 022 023 import org.w3c.dom.Document; 024 import org.w3c.dom.Element; 025 import org.w3c.dom.NamedNodeMap; 026 import org.w3c.dom.Node; 027 028 /** 029 * Exception related to data decoding from a DOM element. 030 */ 031 public class DecodingException extends IOException 032 { 033 private final Element m_element; 034 035 /** 036 * Create a new decoding exception. 037 * @param element the element representing the source of the error 038 * @param message the exception message 039 */ 040 public DecodingException( Element element, String message ) 041 { 042 this( element, message, null ); 043 } 044 045 /** 046 * Create a new decoding exception. 047 * @param element the element representing the source of the error 048 * @param message the exception message 049 * @param cause the causal exception 050 */ 051 public DecodingException( Element element, String message, Throwable cause ) 052 { 053 super( message ); 054 if( null != cause ) 055 { 056 super.initCause( cause ); 057 } 058 m_element = element; 059 } 060 061 /** 062 * Get the element that is the subject of this exception. 063 * @return the subject element 064 */ 065 public Element getElement() 066 { 067 return m_element; 068 } 069 070 /** 071 * Return a string representation of the exception. 072 * @return the string value 073 */ 074 public String getMessage() 075 { 076 try 077 { 078 String message = super.getMessage(); 079 StringBuffer buffer = new StringBuffer( message ); 080 buffer.append( "\n" ); 081 Element element = getElement(); 082 String listing = list( element ); 083 buffer.append( listing ); 084 Document document = element.getOwnerDocument(); 085 String uri = document.getDocumentURI(); 086 if( null != uri ) 087 { 088 buffer.append( "\nDocument: " + uri ); 089 } 090 return buffer.toString(); 091 } 092 catch( Throwable e ) 093 { 094 return super.getMessage(); 095 } 096 } 097 098 /** 099 * Static utility operation that returns a syring representation of a DOM element. 100 * @param element the element to stringify 101 * @return the string value 102 */ 103 public static String list( Element element ) 104 { 105 return list( element, "" ); 106 } 107 108 /** 109 * Static utility operation that returns a syring representation of a DOM element. 110 * @param element the element to stringify 111 * @param pad padding offset 112 * @return the string value 113 */ 114 public static String list( Element element, String pad ) 115 { 116 StringBuffer buffer = new StringBuffer(); 117 String tag = element.getTagName(); 118 buffer.append( pad + "<" ); 119 buffer.append( tag ); 120 NamedNodeMap map = element.getAttributes(); 121 for( int i=0; i<map.getLength(); i++ ) 122 { 123 Node item = map.item( i ); 124 buffer.append( " " + item.getNodeName() + "=\"" ); 125 buffer.append( item.getNodeValue() ); 126 buffer.append( "\"" ); 127 } 128 129 Element[] children = ElementHelper.getChildren( element ); 130 if( children.length > 0 ) 131 { 132 buffer.append( ">" ); 133 for( int i=0; i<children.length; i++ ) 134 { 135 Element child = children[i]; 136 String listing = list( child, pad + " " ); 137 String tagName = child.getTagName(); 138 buffer.append( "\n" + listing ); 139 } 140 buffer.append( "\n" + pad + "</" + tag + ">" ); 141 } 142 else 143 { 144 buffer.append( "/>" ); 145 } 146 return buffer.toString(); 147 } 148 }